
//varying float intensity;


#version 120
//#extension GL_EXT_gpu_shader4 : enable
#extension GL_EXT_geometry_shader4 : enable

uniform mat4 mvMatrix;
uniform mat4 mvpMatrix;
uniform mat3 normalMatrix;
uniform vec4 lightPos;

uniform float edge_size;
uniform float isovalue;
//uniform isampler2D edges_tex;
//uniform isampler2D tritab_tex;

uniform int edges[256];
uniform int tritab[256*16];

float values[8];
vec4 positions[8];

void init_pos_values ()
{
  positions[0] = gl_PositionIn[0];
  positions[1] = gl_PositionIn[0] + vec4(edge_size,0.0,       0.0,      0.0);
  positions[2] = gl_PositionIn[0] + vec4(edge_size,0.0,       edge_size,0.0);
  positions[3] = gl_PositionIn[0] + vec4(0.0,      0.0,       edge_size,0.0);
  positions[4] = gl_PositionIn[0] + vec4(0.0,      edge_size, 0.0,      0.0);
  positions[5] = gl_PositionIn[0] + vec4(edge_size,edge_size, 0.0,      0.0);
  positions[6] = gl_PositionIn[0] + vec4(edge_size,edge_size, edge_size,0.0);
  positions[7] = gl_PositionIn[0] + vec4(0.0,      edge_size, edge_size,0.0);
/////////////////////////////////////////////
  values[0] = length(vec3(positions[0].xyz));
  values[1] = length(vec3(positions[1].xyz));
  values[2] = length(vec3(positions[2].xyz));
  values[3] = length(vec3(positions[3].xyz));
  values[4] = length(vec3(positions[4].xyz));
  values[5] = length(vec3(positions[5].xyz));
  values[6] = length(vec3(positions[6].xyz));
  values[7] = length(vec3(positions[7].xyz));
}

vec4 make_vertex (in float iso, in vec4 pos1, in vec4 pos2, in float v1, in float v2)
{
  //P = p1 + (iso - v1)*(p2-p1)/(v2-v1)
  return pos1 + (pos2 - pos1) * ( (iso-v1) / (v2-v1) );
}

int tritabf (in int i, in int j)
{
  return tritab[256*i+j];
  //return texelFetch2D(tritab_tex, ivec2(i, j),0).a;
}

void main (void)
{
  init_pos_values();
  int index = 0;
  int add=1;
  for(int i=0;i<8;i++){
    if(values[i]<isovalue)
      index+=add;
    add*=2;
  }
  if(index==0 || index==255)
    return;
  int edge_bits = edges[index];
  //int edge_bits = texelFetch2D(edges_tex, ivec2(index, 0), 0).a;;
  vec4 vertlist[12];
  if ((edge_bits & 1) != 0)
    vertlist[0]  = make_vertex(isovalue,positions[0],positions[1],values[0],values[1]);
  if ((edge_bits & 2) != 0)
    vertlist[1]  = make_vertex(isovalue,positions[1],positions[2],values[1],values[2]);
  if ((edge_bits & 4) != 0)
    vertlist[2]  = make_vertex(isovalue,positions[2],positions[3],values[2],values[3]);
  if ((edge_bits & 8) != 0)
    vertlist[3]  = make_vertex(isovalue,positions[3],positions[0],values[3],values[0]);
  if ((edge_bits & 16) != 0)
    vertlist[4]  = make_vertex(isovalue,positions[4],positions[5],values[4],values[5]);
  if ((edge_bits & 32) != 0)
    vertlist[5]  = make_vertex(isovalue,positions[5],positions[6],values[5],values[6]);
  if ((edge_bits & 64) != 0)
    vertlist[6]  = make_vertex(isovalue,positions[6],positions[7],values[6],values[7]);
  if ((edge_bits & 128) != 0)
    vertlist[7]  = make_vertex(isovalue,positions[7],positions[4],values[7],values[4]);
  if ((edge_bits & 256) != 0)
    vertlist[8]  = make_vertex(isovalue,positions[0],positions[4],values[0],values[4]);
  if ((edge_bits & 512) != 0)
    vertlist[9]  = make_vertex(isovalue,positions[1],positions[5],values[1],values[5]);
  if ((edge_bits & 1024) != 0)
    vertlist[10] = make_vertex(isovalue,positions[2],positions[6],values[2],values[6]);
  if ((edge_bits & 2048) != 0)
    vertlist[11] = make_vertex(isovalue,positions[3],positions[7],values[3],values[7]);
  for(int i=0; i<16; i+=3){
    if(tritabf(index,i)!=-1){
      vec4 v[3];
      v[0] = vertlist[tritabf(index,i)];
      gl_Position = mvpMatrix * v[0];
      EmitVertex();
      v[1] = vertlist[tritabf(index,i+1)];
      gl_Position = mvpMatrix * v[1];
      EmitVertex();
      v[2] = vertlist[tritabf(index,i+2)];
      gl_Position = mvpMatrix * v[2];
      EmitVertex();
      EndPrimitive();
    }
    else
      break;
  }
}
